package com.desaysv.svhttp.param;

import android.text.TextUtils;

import com.desaysv.svhttp.handler.type.ParamsType;
import com.desaysv.svhttp.utils.SVUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author linzi
 * @version 1.0
 * @date 2022-7-19
 * @since 2022-7-19
 */
public class HttpParams {
    /**
     * 请求参数的键值
     */
    private final HashMap<String, Object> mParamsMap = new HashMap<>();
    /**
     * 请求头部的键值
     */
    private final HashMap<String, String> mHeaders = new HashMap<>();
    /**
     * 请求文件参数的键值
     */
    private final HashMap<String, File> mFileMap = new HashMap<>();
    /**
     * 请求路径参数的键值
     */
    private final HashMap<String, Object> mPathParams = new HashMap<>();

    private String mJson = null;

    /**
     * 下载文件存放路径的键值
     */
    private String mSavePath = "";
    /**
     * 单次请求自定义请求地址
     */
    private String mSingleUrl;
    /**
     * 默认的contentType
     */
    private ParamsType mContentType = ParamsType.DEFAULT_FORM;
    /**
     * mBoundary
     */
    private String mBoundary = null;

    /**
     * 设置ct
     *
     * @param typs {@link com.desaysv.svhttp.handler.type.ParamsType}
     * @return HttpParams
     */
    public HttpParams setContentType(ParamsType typs) {
        this.mContentType = typs;
        return this;
    }

    /**
     * @return 获取自定义的ct {@link com.desaysv.svhttp.handler.type.ParamsType}
     */
    public ParamsType getContentType() {
        mBoundary = String.format("%s", SVUtils.getRandom(10, SVUtils.TYPE.LETTER_CAPITAL));
        return mContentType;
    }

    /**
     * @return 获取mBoundary
     */
    public String getBoundary() {
        if (mBoundary == null) {
            mBoundary = String.format("%s", SVUtils.getRandom(10, SVUtils.TYPE.LETTER_CAPITAL));
        }
        return mBoundary;
    }

    /**
     * @param key   参数名
     * @param value 参数值
     * @return HttpParams
     * @author linzi
     * @date 2022-8-25 17:45
     * @context 添加参数
     */
    public HttpParams addParams(String key, Object value) {
        mParamsMap.put(key, value);
        return this;
    }

    /**
     * @param key   路径参数名
     * @param value 路径参数
     * @return HttpParams
     * @author linzi
     * @date 2022-8-25 17:45
     * @context 添加参数
     */
    public HttpParams addPathParams(String key, Object value) {
        mPathParams.put(key, value);
        return this;
    }

    /**
     * @param key   自定义请求头参数名
     * @param value 自定义请求头数据
     * @return HttpParams
     * @author linzi
     * @date 2022-8-25 17:46
     * @context 添加自定义请求头
     */
    public HttpParams addHeader(String key, String value) {
        mHeaders.put(key, value);
        return this;
    }

    /**
     * @param savePath 文件保存路径
     * @return HttpParams
     * @author linzi
     * @date 2022-8-25 17:46
     * @context 设置下载路径
     */
    public HttpParams setSavePath(String savePath) {
        this.mSavePath = savePath;
        return this;
    }

    /**
     * @return 获取文件保存路径
     */
    public String getSavePath() {
        return this.mSavePath;
    }

    /**
     * @param mSingleUrl 设置单次请求的请求路径
     * @return HttpParams
     * @author linzi
     * @date 2022-8-25 17:46
     * @context 设置单次请求的地址
     */
    public HttpParams setSingleUrl(String mSingleUrl) {
        this.mSingleUrl = mSingleUrl;
        return this;
    }

    /**
     * @return 获取路径参数
     */
    public HashMap<String, Object> getPathParams() {
        return mPathParams;
    }

    /**
     * @return 获取单次请求路径
     */
    public String getSingleUrl() {
        return this.mSingleUrl;
    }

    /**
     * @return 获取元数据
     */
    public Map<String, Object> getSourceMap() {
        return mParamsMap;
    }

    /**
     * @return application/x-www-form-urlencoded请求参数
     * @author linzi
     * @date 2022-8-25 17:44
     * @context application/x-www-form-urlencoded请求参数构建
     */
    public String getParams() {
        int pos = 0;
        //请求参数
        StringBuilder tempParams = new StringBuilder();
        try {
            if (!mParamsMap.isEmpty()) {
                for (String key : mParamsMap.keySet()) {
                    if (pos > 0) {
                        tempParams.append("&");
                    }
                    tempParams.append(String.format("%s=%s", key, URLEncoder.encode(Objects.requireNonNull(mParamsMap.get(key)).toString(), "utf-8")));
                    pos++;
                }
            } else {
                tempParams = new StringBuilder();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return tempParams.toString();
    }

    /**
     * @return 请求头部
     */
    public Map<String, String> getHeaders() {
        return mHeaders;
    }

    /**
     * @return 文件集合
     */
    public Map<String, File> getFiles() {
        return mFileMap;
    }

    /**
     * @return 表单请求参数
     * @author linzi
     * @date 2022-8-25 17:45
     * @context 表单参数构建
     */
    public String getFormData() {
        StringBuilder sb = new StringBuilder();
        if (mParamsMap.size() == 0) {
            return sb.toString();
        }
        getBoundary();
        for (String s : mParamsMap.keySet()) {
            if (mParamsMap.get(s) instanceof File) {
                mFileMap.put(s, (File) mParamsMap.get(s));
                continue;
            }
            sb.append(String.format("--%s\r\n", mBoundary));
            sb.append(String.format("Content-Disposition: form-data; name=\"%s\"\r\n", s));
            sb.append("\r\n");
            sb.append(String.format("%s\r\n", mParamsMap.get(s)));
        }
        if (sb.length() > 0 && mFileMap.size() == 0) {
            sb.append(String.format("--%s--\r\n", mBoundary));
        }
        return sb.toString();
    }

    /**
     * @return json参数
     * @throws JSONException json异常信息
     * @author linzi
     * @date 2022-8-25 17:45
     * @context json参数构建
     */
    public String getJsonData() throws JSONException {
        if (!TextUtils.isEmpty(mJson)) {
            return mJson;
        }
        JSONObject jsonObject = new JSONObject();
        for (String s : mParamsMap.keySet()) {
            jsonObject.put(s, mParamsMap.get(s));
        }
        return jsonObject.toString();
    }

    public void setJson(String mJson) {
        this.mJson = mJson;
    }
}


